package com.bikes.mileagetracker.utils



class DistanceUtils {

    private val DEF_PI = 3.14159265359 // PI
    private val DEF_2PI = 6.28318530712 // 2*PI
    private val DEF_PI180 = 0.01745329252 // PI/180.0
    private val DEF_R = 6370693.5 // radius of earth

    /**
     * 返回为m，适合短距离测量
     *
     * @param lon1 The start location's longitude.
     * @param lat1 The start location's latitude.
     * @param lon2 The end location's longitude.
     * @param lat2 The end location's latitude.
     * @return The distance, the unit is mile.
     */
    fun measureShortDistance(lon1: Double, lat1: Double, lon2: Double, lat2: Double): Double {
        val ew1: Double = lon1 * DEF_PI180
        val ns1: Double = lat1 * DEF_PI180
        val ew2: Double = lon2 * DEF_PI180
        val ns2: Double = lat2 * DEF_PI180
        val dx: Double
        val dy: Double
        var dew: Double
        // 角度转换为弧度
        // 经度差
        dew = ew1 - ew2
        // 若跨东经和西经180 度，进行调整
        if (dew > DEF_PI)
            dew = DEF_2PI - dew
        else if (dew < -DEF_PI)
            dew += DEF_2PI
        dx = DEF_R * Math.cos(ns1) * dew // 东西方向长度(在纬度圈上的投影长度)
        dy = DEF_R * (ns1 - ns2) // 南北方向长度(在经度圈上的投影长度)
        // 勾股定理求斜边长
        return Math.sqrt(dx * dx + dy * dy)
    }

    /**
     * 返回为m,适合长距离测量
     *
     * @param lon1 The start location's longitude.
     * @param lat1 The start location's latitude.
     * @param lon2 The end location's longitude.
     * @param lat2 The end location's latitude.
     * @return The distance, the unit is mile.
     */
    fun getLongDistance(lon1: Double, lat1: Double, lon2: Double, lat2: Double): Double {
        val ew1: Double = lon1 * DEF_PI180
        val ns1: Double = lat1 * DEF_PI180
        val ew2: Double = lon2 * DEF_PI180
        val ns2: Double = lat2 * DEF_PI180
        var distance: Double
        // 角度转换为弧度
        // 求大圆劣弧与球心所夹的角(弧度)
        distance = Math.sin(ns1) * Math.sin(ns2) + (Math.cos(ns1) * Math.cos(ns2)
                * Math.cos(ew1 - ew2))
        // 调整到[-1..1]范围内，避免溢出
        if (distance > 1.0)
            distance = 1.0
        else if (distance < -1.0)
            distance = -1.0
        // 求大圆劣弧长度
        return DEF_R * Math.acos(distance)
    }


}